#ifndef SOLID_LOADER_H
#define SOLID_LOADER_H
#include <list>
#include <iosfwd>
#include <string>
#include "globals.h"
#include "scene.h"
#include "matrix.h"

//serve to load objects into scene

namespace gemren
{
	struct studio;
	class solid_loader
	{
	public:
		struct solid_data
		{//for threads' use
			//input
			matrix4x4 transmat;
			material_ptr mat;
			std::string filename;
			//solid_data(){}
			solid_data(const matrix4x4& transmat, const material_ptr mat, const std::string filename, const std::map<std::string,std::string>& groupmat, const std::string& matname = "" )
				: 
				transmat(transmat), 
				mat(mat), 
				filename(filename), 
				groupmat(groupmat)
			{
				if(matname.size()>0)
				this->groupmat["default"] = matname;
			}
			
			//output
			std::list<coord> verts, norms;
			std::list<coord2d> texs;
			std::list<triangle> tris; 
			std::map<std::string,std::string> groupmat;
			std::map<std::string, material_ptr> materials;
			
			
			void copy_data(solid_data& d)
			{
				verts.swap(d.verts);
				norms.swap(d.norms);
				texs.swap(d.texs);
				tris.swap(d.tris);
				materials.swap(d.materials);
			}

		private:
			solid_data& operator=(const solid_data&);
		};
	public:
		static studio load_scene(const std::string& filename);
	protected:
		static bool load_def(studio& stud, std::list<std::string>& configs, std::vector<solid_data>& solids, const std::string& filename, const std::map<std::string,std::string>& parent_groupmat, const matrix4x4& transmat = matrix4x4::identity(), const material_ptr mat = 0) ;
		static bool load_def(studio& stud, std::list<std::string>& configs, std::vector<solid_data>& solids, std::istream& datastream, const std::map<std::string,std::string>& parent_groupmat, const matrix4x4& transmat = matrix4x4::identity(), const material_ptr mat = 0);

		
	};
}
#endif